import { TEAMMATE_DATA, type TeammateType } from '../../data/teammate';
import type { AttributeType } from '../attributes/type';
import {
  CombatAttributes,
  type AttributesConfig,
} from '../attributes/combat-attributes';

/**
 * 队友配置接口
 * 定义创建队友所需的配置参数
 */
export interface TeammateConfig {
  /** 队友唯一标识 */
  id: string;
  /** 队友名称 */
  name: string;
  /** 队友描述 */
  description?: string;
  /** 队友类型 */
  type: TeammateType;
  /** 属性配置 */
  attributesConfig: AttributesConfig;
}

/**
 * 队友实体类
 * 代表游戏中的一个队友实例
 */
export class Teammate {
  /** 队友唯一标识 */
  readonly id: string;
  /** 队友名称 */
  readonly name: string;
  /** 队友描述 */
  readonly description?: string;
  /** 队友类型 */
  readonly type: TeammateType;
  /** 队友属性管理 */
  readonly attributes: CombatAttributes;

  /**
   * 构造函数
   * @param config 队友配置
   */
  constructor(config: TeammateConfig) {
    this.id = config.id;
    this.name = config.name;
    this.description = config.description;
    this.type = config.type;
    this.attributes = new CombatAttributes(config.attributesConfig);
  }

  /**
   * 获取队友属性快照
   * @returns 包含所有属性信息的快照
   */
  getAttributeSnapshot() {
    return this.attributes.getAttributeSnapshot();
  }

  /**
   * 获取指定属性的最终值
   * @param attributeKey 属性键
   * @returns 属性数值
   */
  getAttributeValue(attributeKey: AttributeType): number {
    return this.attributes.getAttributeValue(attributeKey);
  }

  /**
   * 获取队友基本信息
   * @returns 基本信息对象
   */
  getInfo() {
    return {
      id: this.id,
      name: this.name,
      description: this.description,
      type: this.type,
    };
  }
}

/**
 * 队友工厂类
 * 用于批量创建和管理敌人实体
 */
export class TeammateFactory {
  /**
   * 根据 ID 创建敌人实体
   * @param teammateId 队友 ID
   * @returns 敌人实体实例
   * @throws 当敌人 ID 未注册时抛出错误
   */
  public static createTeammateById(
    teammateId: string,
    options?: {
      level?: number;
    }
  ): Teammate {
    const config = TEAMMATE_DATA.find((config) => config.id === teammateId);
    if (!config) {
      throw new Error(`未找到 ID 为 "${teammateId}" 的队友配置`);
    }
    const mode = config.attributesConfig.mode;
    switch (mode) {
      case 'fixed':
        return this.createFixedAttributeTeammateById(config);
      case 'level':
        if (options?.level === undefined) {
          throw new Error('等级成长属性敌人必须提供 options.level 参数');
        }
        return this.createLevelGrowthAttributeEnemyById(options.level, config);
      default:
        return new Teammate(config);
    }
  }

  /**
   * 根据配置创建固定属性的敌人实体
   * @param teammateId 队友 ID
   * @returns 敌人实体实例
   */
  public static createFixedAttributeTeammateById(
    config: TeammateConfig
  ): Teammate {
    if (config.attributesConfig.fixedAttributes === undefined) {
      throw new Error(
        '固定属性敌人必须提供 attributesConfig.fixedAttributes 参数'
      );
    }
    return new Teammate({
      ...config,
      attributesConfig: {
        mode: 'fixed',
        fixedAttributes: config.attributesConfig.fixedAttributes,
      },
    });
  }

  /**
   * 根据配置创建对应等级成长属性的敌人实体
   * @param enemyId 队友 ID
   * @returns 敌人实体实例
   */
  public static createLevelGrowthAttributeEnemyById(
    level: number,
    config: TeammateConfig
  ): Teammate {
    if (config.attributesConfig.levelBasedConfig === undefined) {
      throw new Error(
        '等级成长属性敌人必须提供 attributesConfig.levelBasedConfig 参数'
      );
    }
    return new Teammate({
      ...config,
      attributesConfig: {
        mode: 'level',
        levelBasedConfig: {
          ...config.attributesConfig.levelBasedConfig,
          initialLevel: level,
        },
      },
    });
  }
}
